Introduction to Tick Layer
What is a tick layer?
A tick is largely similar to a point mark except for the fact that it has a start point and an end point and thus is always a straight line.
Example
const { muze, getDataFromSearchQuery } = viz;
const data = getDataFromSearchQuery();
const RowField = "Cylinders";
const ColumnField = "Horsepower";
const DetailField = "Name";
muze
.canvas()
.rows([RowField])
.columns([ColumnField])
.detail([DetailField])
.layers([
{
mark: "tick",
},
])
.data(data)
.mount("#chart");
Creating a dotplot using tick layer
Example
const { muze, getDataFromSearchQuery } = viz;
const data = getDataFromSearchQuery();
const RowField = "Acceleration";
const ColumnField = "Year";
const ColorField = "Origin";
const DetailField = "Name";
muze
.canvas()
.rows([RowField])
.columns([ColumnField])
.color(ColorField)
.detail([DetailField])
.layers([
{
mark: "tick",
},
])
.data(data)
.mount("#chart");
Creating a reference line
Below is an example of creating a reference line on a bar chart.
We will add a bar layer for visualizing Year vs Horsepower, a tick layer for showing the average value and a text layer displaying the actual average value.
Example
const { muze, getDataFromSearchQuery } = viz;
const data = getDataFromSearchQuery();
const YearField = "Year";
const HorsepowerField = "Horsepower";
const AverageLineSourceName = "averageLine";
const CompositeBarName = "compositeBar";
let dm = data;
dm = dm.groupBy([YearField]);
dm = dm.sort([[HorsepowerField, "DESC"]]);
let layerFactory = muze.layerFactory;
// Compose layers to draw the bars as well as the reference line and text
layerFactory.composeLayers(CompositeBarName, [
{
name: "simplebar",
mark: "bar",
encoding: {
x: `${CompositeBarName}.encoding.x`,
y: `${CompositeBarName}.encoding.y`,
color: `${CompositeBarName}.encoding.color`,
},
},
{
name: "averageLine",
mark: "tick",
source: AverageLineSourceName,
className: "averageLine",
encoding: {
y: `${CompositeBarName}.encoding.y`,
x: null,
},
calculateDomain: false,
},
{
name: "averageText",
mark: "text",
source: AverageLineSourceName,
className: "averageText",
encoding: {
y: `${CompositeBarName}.encoding.y`,
text: `${CompositeBarName}.encoding.text`,
background: {
enabled: true,
},
},
encodingTransform: (points, layer, dependencies) => {
// Transforms the test after the physical dimension is resolved so that it comes in the middle of the background
let width = layer.measurement().width;
let smartLabel = dependencies.smartLabel;
for (let i = 0; i < points.length; i++) {
let size = smartLabel.getOriSize(points[i].text);
points[i].update.x = width - 5;
points[i].textanchor = "end";
points[i].update.y -= size.height / 2;
points[i].color = "#000";
}
return points;
},
calculateDomain: false,
},
]);
muze
.canvas()
.rows([HorsepowerField])
.columns([YearField])
.transform({
// Create different sources (data) from the root source (data). Layers can access these sources and draw any visualization
[AverageLineSourceName]: (dt) => dt.groupBy([""]), // Removes all the dim and aggregate the measures
})
.layers([
{
mark: "bar",
},
{
mark: "text",
encoding: {
x: {
field: null,
value: (d, i) => {
return i.context.measurement().width - 80;
},
},
y: {
field: HorsepowerField,
value: (d) => {
return d.y - 10;
},
},
text: {
field: HorsepowerField,
formatter: (value) => {
return `Average Horsepower: ${Math.round(value)}`;
},
},
color: {
value: () => "black",
},
},
source: AverageLineSourceName,
},
{
mark: "tick",
className: "averageLine",
encoding: {
x: {
field: null,
},
y: HorsepowerField,
color: {
value: () => "black",
},
},
source: AverageLineSourceName,
},
])
.title("Sorted bar with trendline", { position: "top", align: "left" })
.subtitle(
"Average horsepower per year with average horsepower of all time marked as reference",
{ position: "top", align: "left" },
)
.data(dm)
.mount("#chart");